class Snake {
  constructor() {
    this.body = [
      {
        x: 0,
        y: 0,
      },
    ];
    this.direction = "left";
    this.newDirection = "right";
  }
  //   更新蛇的位置
  update() {
    this.direction = this.newDirection;
    const head = { ...this.body[0] };
    switch (this.direction) {
      case "up":
        head.y = head.y - 10;
        // head.y--;
        break;
      case "down":
        head.y = head.y + 10;
        // head.y++;
        break;
      case "left":
        head.x = head.x - 10;
        // head.x--;
        break;
      case "right":
        head.x = head.x + 10;
        // head.x++;
        break;
    }
    console.log(this.body, "==");
    this.body.unshift(head);
    this.body.pop();
  }

  //   改变方向(确保不能反向)
  changeDirection(newDir) {
    const oppositeDirs = {
      up: "down",
      down: "up",
      left: "right",
      right: "left",
    };
    if (newDir !== oppositeDirs[this.direction]) {
      this.newDirection = newDir;
    }
  }

  //   检查是否吃到食物
  checkEat(food) {
    const head = this.body[0];
    return head.x === food.x && head.y === food.y;
  }

  //   增加身体长度
  grow() {
    this.body.push({
      ...this.body[this.body.length - 1],
    });
  }

  //   检查碰撞 撞墙或者自身
  checkCollisiton() {
    const head = this.body[0];
    // 撞墙 宽高400 400 x y 通过++重新渲染矩形移动位置 自身宽高20 * 20 最大x y 理论不能超过380
    // 但是这样会吃不到靠墙的食物 改为 390
    if (head.x < 0 || head.x >= 390 || head.y < 0 || head.y >= 390) {
      return true;
    }
    // 撞自身
    if (this.body.length === 1) {
      return false;
    }
    // for (let i = 0; i < this.body.length; i++) {
    //   if (head.x === this.body[i].x && head.y === this.body[i].y) {
    //     return true;
    //   }
    // }
    return false;
  }

  // 重置
  reset() {
    this.body = [
      {
        x: 0,
        y: 0,
      },
    ];
    this.direction = "left";
    this.newDirection = "right";
  }
}

class Food {
  constructor() {
    this.x = 0;
    this.y = 0;
    this.respawn();
  }
  //   x y 位置随机生成
  respawn() {
    this.x = this.getRandomInt(1, 38) * 10;
    this.y = this.getRandomInt(1, 38) * 10;
  }

  getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
  }
}

// 游戏控制逻辑
class Game {
  constructor(canvasId, gridSize = 20) {
    this.canvas = document.getElementById(canvasId);
    this.ctx = this.canvas.getContext("2d");
    this.gridSize = gridSize; // 网格数量20 * 20
    this.cellSize = this.canvas.width / gridSize; // 每个格子大小
    this.snake = new Snake();
    this.food = new Food();
    this.score = 0;
    this.gameLoop = null;
    this.isGameOver = false;
    this.time = 0;
    // 绑定键盘事件
    document.addEventListener("keydown", (e) => this.handleKeyPress(e));
  }

  //   处理键盘输出
  handleKeyPress(e) {
    const dirMap = {
      ArrowUp: "up",
      ArrowDown: "down",
      ArrowLeft: "left",
      ArrowRight: "right",
    };
    if (dirMap[e.key] && !this.isGameOver) {
      this.snake.changeDirection(dirMap[e.key]);
    }
  }

  //   游戏主循环
  start() {
    this.gameLoop = setInterval(() => {
      this.time++;
      this.draw();
      this.update();
    }, 200); // 游戏速度
  }

  //   更新游戏状态
  update() {
    if (this.isGameOver) return;
    this.snake.update();
    document.getElementById("time").textContent = this.time;
    // 检查是否吃到食物
    if (this.snake.checkEat(this.food)) {
      this.snake.grow();
      this.food.respawn();
      this.score += 10;
      document.getElementById("score").textContent = this.score;
    }
    // 检查碰撞
    if (this.snake.checkCollisiton()) {
      this.gameOver();
    }
  }

  //   绘制游戏画面
  draw() {
    this.ctx.fillStyle = "#0ba6eb"; // 颜色
    this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); // 填充矩形 (x, y, width, height)
    // 绘制蛇
    this.ctx.fillStyle = "red";
    this.snake.body.forEach((segment) => {
      this.ctx.fillRect(segment.x, segment.y, this.cellSize, this.cellSize);
    });
    // 绘制食物
    this.ctx.fillStyle = "green";
    this.ctx.fillRect(this.food.x, this.food.y, this.cellSize, this.cellSize);

    // 游戏结束文字
    if (this.isGameOver) {
      this.ctx.fillStyle = "#000";
      this.ctx.font = "30px Arial";
      this.ctx.fillText("游戏结束！", 150, 200);
      this.ctx.fillText("点击空格重新开始", 100, 250);
    }
  }

  //   结束游戏
  gameOver() {
    this.isGameOver = true;
    this.draw(); // 绘制停止游戏
    this.snake.reset();
    this.reset();
  }

  // 重新开始游戏
  restart() {
    this.start();
  }

  //   逻辑重置
  reset() {
    clearInterval(this.gameLoop);
    this.gameLoop = null;
    this.snake = new Snake();
    this.food = new Food();
    this.score = 0;
    this.isGameOver = false;
    this.time = 0;
  }
}
addEventListener("keyup", function (e) {
  if (e.key === " ") {
    const game = new Game("gameCanvas");
    game.start();
  }
});
// 启动游戏
